查看原文
其他

开发SDK和平时写代码体验不同吗? | 经验分享

2017-12-15

作者 brucevanfdm

每日推荐


推荐一个BLE蓝牙研究的库,正在做该方面的或者有兴趣的可以看下。


Android BLE蓝牙框架,包括扫描、连接、设置通知、发送数据、读取和接收数据以及各种直观的回调,近乎一行代码植入项目,可扩展配置蓝牙相关操作。


https://github.com/Alex-Jerry/BleDemo

http://www.jianshu.com/p/d70e22ce61bc


本文作者


作者:brucevanfdm

链接:

http://www.jianshu.com/p/8f39919cd4e5

本文由作者授权发布。


1前言


最近由于工作需要,将应用里的部分功能独立了出来,封装成 SDK 提供给合作伙伴使用。由于经验不足,网上也没多少写这方面内容的文章,遇到了不少的坑,决定记录下来。


其实,刚说到要写SDK也有点慌,印象中SDK一直是个复杂的东西,脑海中浮现的是Java SDK ,Android SDK这类庞然大物。


SDK全称 Software Development Kit,广义上的 SDK 是为特定的软件包、软件框架、硬件平台、操作系统等建立应用程序时所使用的开发工具的集合,狭义上的 SDK 则是基于系统 SDK 进行开发包装的、新的、独立的、能够完成特定功能并返回相关数据的一组工具的集合。


听起来一愣一愣的,其实,将一些业务逻辑独立出来,打包成jar、so、aar,暴露一些APIs给外部调用,也可以称为SDK。如推送SDK,支付SDK,地图SDK...既然是所谓的集合,那么自然有大有小。


下面说说我在封装SDK与使用的时候遇到的那些事,希望对大家有些帮助吧!


2二次打包aar


大多时候,我们的业务依赖于第三方库,载体可能为jar、so、aar,如果是jar包那好办,直接丢进libs目录下就可以了;so库就不简单了,不少开发商只提供少数abi的so库,这时就需要根据需求选择了,要么全部一份,要么只保留一个目录,否则就会报错;aar则是包含了代码、资源(图片、布局等)、so库等的集合。


那么需求来了,如何将第三方aar包二次封装,加入自己的业务逻辑再打包成一个aar呢?其实这个问题我也没有找到直接的解决方案,如果你有,请联系我,感激不尽!但是这个问题又是可以曲线解决的,aar其实就是个压缩包而已,如下图所示:



Android Studio导入aar时也是将其视为一个module(library),使用其中的classes以及其他资源文件,那我们可不可以直接将其解压,直接导入?


这样就避免了在aar的基础上封装成aar!跳过这个坑?实践证明确实是可以的。如果你要封装的aar只包含了jar包和so库,那就简单了,解压出来分别导入项目相关目录即可!不然可能就要手动合并某些资源了...更新:详情请看 二次打包(封装)AAR实用指南


http://www.jianshu.com/p/3bad128bd106


还是期待谷歌能给出一个傻瓜式的一键合并方案吧!


3SDK中Application对象的初始化


有次SDK接入方反馈说某个地方崩溃了,一看Log,是调用Application对象中的方法空指针了。我一想,混淆?不是。导入姿势不对?不是。文档没认真看?也不是?Demo可以正常运行啊......随即想到是接入方自定义Application对象的问题。


如果aar中定义了Application,theme,icon,那么编译时就要抛出如下异常:


-编译错误AndroidManifest合并异常-


由于项目与aar都定义了自己的Application,编译器不知道用谁的,这就产生了上图的异常,按照提示,在Application标签下添加如下代码:


tools:replace="android:name"


合并方案可以参考官方文档:合并多个清单文件| Android Studio - Android Developers

https://developer.android.com/studio/build/manifest-merge.html?hl=zh-cn


理虽如此,但是你很大概率就掉坑了,这个方案直接将SDK中的Application对象替换为你的,换句话说就是SDK中的Application对象根本没有初始化,这就是上文说的空指针的罪魁祸首了!


确实之前在写文档的时候没有考虑到自定义Application的情况,还是经验不足啊!甚至一度将Application里初始化的方法全部移出来,后来转念一想,让接入方继承我的Application不就OK了吗!!测试一波,赶紧更新下文档,不然又被吐槽了...这下理解为什么接入某些第三方SDK时,有的会要求继承SDK里定义的Application对象。


4Application多继承


作为一个SDK提供方,假如你的SDK需要用户继承你的Application,我觉得应当提供一个Application多继承的解决方案,毕竟用户可能不仅仅只用你一个SDK,当有多个SDK有这个需求时就尴尬了。


java 多继承,这里的需求是继承两个类,并不是通过实现接口的方式“继承”多个接口上的方法声明。语言原生不支持,这样就比较麻烦了。


解决办法如下:


通过接口实现 + 反射 的方式来创建代理Application对象,曲线实现Application的多继承,由于代码较多,这里就不贴源码了,解决方案:ApplicationProxyDemo 源码配合注释食用,风味更佳!

https://github.com/brucevanfdm/ApplicationProxyDemo


5导入aar的两种方法


解决一:采用Android Studio新建module的方法,选择jar/aar即可。



导入.AAR


解决二:使用gradle脚本直接导入:


1. 在项目build.gradle文件内android{}标签中加入如下代码申明本地仓库:


repositories {
       flatDir {
           dirs 'libs'
       }
   }
}


2. 然后将aar包放入libs目录(没有就在app目录下创建一个),随后加入dependencies :


dependencies {
   compile fileTree(dir: 'libs', include: ['*.jar'])
   ...
   compile(name: 'xxxxxx-xxxx', ext: 'aar') //name为aar文件全名
}


6SDK中不可忽视的混淆问题


1. 常规的避免混淆,比如一些第三方类库中的要求

2. 避免混淆对外提供方法与数据实体的类,并且添加到接入方的proguard-rules.pro中。

最后


其实在最近的SDK开发与对接中遇到了不少问题,但是也学到了不少东西,由于缺少相关经验,也在不断的摸索之中。正所谓实战出真知,纸上谈兵容易,真刀真枪时就会暴露出一些问题,还是要多动手。当然了,技术都是业务驱动的。


推荐阅读

上一篇:文末赠书 | WebView截长图解决方案

谈谈Sdk迭代开发设计需要考虑的方面


最后,最近玩Android对文章展示进行了支持,测试阶段,测试页面:

http://www.wanandroid.com/blog/4

大家可以多提提意见~


如果你想要跟大家分享你的文章,欢迎投稿~


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存